package com.zane.common.utils;

import com.zane.common.propertiees.JwtProperties;
import com.zane.common.security.MyUserDetails;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class JwtUtil {
    private final JwtProperties jwtProperties;
    private final SecretKey secretKey;
    public JwtUtil(JwtProperties jwtProperties) {
        this.jwtProperties = jwtProperties;
        this.secretKey = Keys.hmacShaKeyFor(jwtProperties.getSecret().getBytes());
    }
    // 根据username创建token
    public String generateTokenByUsername(String username){
        log.info("基于用户名生成token：{}",username);
        Map<String,Object> claims = new HashMap<>();
        return generateToken(username, claims, jwtProperties.getExpire());
    }
    // 根据myUserDetails类创建token
    public String generateTokenByUserDetails(MyUserDetails userDetails){
        log.info("基于userDetails生成token：{}",userDetails);
        Map<String,Object> claims = new HashMap<>();
        claims.put("userId",userDetails.getUserId());
//        claims.put("roleName",userDetails.getRoleName());
        return generateToken(userDetails.getUsername(), claims, jwtProperties.getExpire());
    }
    // 创建token
    private String generateToken(String subject, Map<String,Object> claims,Long expire){
        return Jwts.builder()
                .setClaims(claims)  // 先设置自定义声明
                .setSubject(subject)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .signWith(secretKey)
                .compact();
    }
    // 验证token是否有效
    public boolean validateToken(String token){
        log.info("验证token：{}",token);
        try{
            // 尝试获取token的声明
            getAllClaiimsFromToken(token);
            return true;
        }catch(Exception e){
            log.warn("token验证失败：{}",e.getMessage());
            return false;
        }
    }
    // 获取token的过期时间
    public Date getExpireFromToken(String token){
        log.info("获取token的过期时间：{}",token);
        Date expiration = getAllClaiimsFromToken(token).getExpiration();
        return expiration;
    }
    // 获取token的username
    public String getUsernameFromToken(String token){
        log.info("获取token的username：{}",token);
        String username = getAllClaiimsFromToken(token).getSubject();
        return username;
    }
    // 获取token的userId
    public Long getUserIdFromToken(String token) {
        log.info("获取token的userId：{}", token);
        Long userId = getAllClaiimsFromToken(token).get("userId",Long.class);
        return userId;
    }
    public Long getExpire(){
        return jwtProperties.getExpire();
    }
    // 获取token的所有声明
    private Claims getAllClaiimsFromToken(String token){
        log.info("获取token的所有声明：{}",token);
        return Jwts.parserBuilder()
                .setSigningKey(secretKey)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
}
